﻿/*
* MaskValidate Class
* A class MaskValidate seta as máscaras para os campos definidos no formulário.
* Utiliza a class Formats para formatar os campos. Cada formato criado lá passa a ser válido aqui, 
* basta defini-lo no nó (fType) do _arrayField.
*
*
* @author		Rodrigo Moyle e Guilherme Almeida
* @version		1.0
*
* http://code.google.com/p/formup/
*
* //////////////////////////////////////////////////////////////////////////////
*
* Esse código é baseado no algorítimo de Carlos R. L. Rodrigues [JSFromHell.com]
*
*/
class FlashForm.MaskValidate {
	var format:String;
	var rules:String;
	var field:TextField;
	var autoTab:TextField;
	var callNoAccept:Function;
	//
	function MaskValidate(format:String, field:TextField, autoTab:TextField, callNoAccept:Function) {
		this.format = format;
		this.rules = '9CX';
		this.field = field;
		this.autoTab = autoTab;
		this.callNoAccept = callNoAccept;
		this.init();
	}
	//
	public function accepts(rules:String, fValue:String):Boolean {
		for (var i = 0; i<rules.length; i++) {
			var rule = rules.substr(i, 1);
			if (accept(rule, fValue)) {
				return true;
			}
		}
		return false;
	}
	/**
	* accept(rule,fValue) faz o controle permanente dos dados que tentam ser inputados nos campos.
	* Para cada máscara fornece as devidas permições.
	*/
	public function accept(rule:String, fValue:String) {
		switch (rule) {
		case '9' :
			return !isNaN(Number(fValue));
			break;
		case 'C' :
			var wordCodes = [[65, 90], [97, 122], [192, 207], [209, 214], [217, 221], [224, 228], [231, 246], [249, 253], 255];
			var codeValor = ord(fValue);
			for (var code in wordCodes) {
				code = wordCodes[code];
				if (code.length) {
					if (codeValor>=code[0] && codeValor<=code[1]) {
						return true;
					}
				} else {
					if (codeValor == code) {
						return true;
					}
				}
			}
			return false;
			break;
		case 'X' :
			return this.accept('9', fValue) || this.accept('C', fValue);
			break;
		}
	}
	/**
	* A função que inicializa o controle de máscara dos campos, para cada campo o evento onChanged é escutado
	* e controlado para que somente os valores e ações permitidas sejam possíveis.
	*/
	public function init() {
		var self = this;
		this.field.onChanged = function() {
			var thenBegin = Selection.getBeginIndex();
			var rule = self.format.substr(thenBegin, 1);
			//
			if (Key.getCode() == Key.BACKSPACE) {
				while (self.rules.indexOf(rule) == -1) {
					this.text = this.text.substring(0, thenBegin-1)+this.text.substr(thenBegin);
					thenBegin--;
					rule = self.format.substr(thenBegin, 1);
				}
				Selection.setSelection(thenBegin, thenBegin);
			} else if (Key.getCode() == Key.DELETEKEY) {
				while (self.rules.indexOf(rule) == -1) {
					this.text = this.text.substring(0, thenBegin)+this.text.substr(thenBegin+1);
					thenBegin++;
					rule = self.format.substr(thenBegin, 1);
				}
				Selection.setSelection(thenBegin, thenBegin);
			} else {
				var thenBegin = Selection.getBeginIndex()-1;
				var rule = self.format.substr(thenBegin, 1);
				var char = this.text.substr(thenBegin, 1);
				//
				while (self.rules.indexOf(rule) == -1) {
					thenBegin++;
					rule = self.format.substr(thenBegin, 1);
				}
				if (!self.accept(rule, char)) {
					this.text = this._lastText;
					if (this.text.length<self.format.length) {
						self.callNoAccept(this._parent);
					}
				}
				if (thenBegin != (Selection.getBeginIndex()-1)) {
					Selection.setSelection(thenBegin+1, thenBegin+1);
				}
			}
			self.addFormat();
			this._lastText = this.text;
			//
			if (self.autoTab && self.field.length == self.format.length) {
				Selection.setFocus(self.autoTab);
			}
		};
		this.field.onSetFocus = function() {
			this._lastText = this.text;
		};
	}
	/**
	* isValid retorna ao Flash se os campos estão preenchidos em sua totalidade, conforme a máscara.
	*/
	function isValid():Boolean {
		if (this.format.length<=this.field.text.length) {
			return true;
		} else {
			return false;
		}
	}
	/**
	* Cria a formatação. E faz o controle da posição do cursor.
	*/
	public function addFormat() {
		var fValue = this.field.text;
		var format = this.format;
		var formated = '';
		var thenBegin = Selection.getBeginIndex();
		//
		for (var i = 0; i<fValue.length; i++) {
			var char = fValue.substr(i, 1);
			if (accepts(this.rules, char)) {
				formated += char;
			} else {
				if (i<=thenBegin) {
					thenBegin--;
				}
			}
		}
		//
		fValue = formated;
		formated = '';
		if (fValue != '') {
			for (var i = 0; i<=Math.min(format.length, fValue.length); i++) {
				var rule = format.substr(i, 1);
				var char = fValue.substr(i, 1);
				if (accept(rule, char)) {
					formated += char;
				} else {
					if (this.rules.indexOf(rule) == -1) {
						formated += rule;
						fValue = formated+fValue.substr(i);
						if (i<=thenBegin) {
							thenBegin++;
						}
					}
				}
			}
		}
		this.field.text = formated;
		Selection.setSelection(thenBegin, thenBegin);
	}
}
